const User = require('../models/users')
const jsonwebtoken = require('jsonwebtoken');
const Question = require('../models/questions');
const Answer = require('../models/answers');

// 验证jwt是否合法，是否失效
const { secret } = require('../config');

class UsersCtl {

  // 只能自己对自己操做（中间件）
  async checkOwner(ctx, next) {
    if (ctx.params.id !== ctx.state.user._id) { ctx.throw(403, '没有权限'); }
    await next();
  }
  // 用户是否存在（中间件）
  async checkUserExist(ctx, next) {
    const user = await User.findById(ctx.params.id);
    if (!user) { ctx.throw(404, '用户不存在'); }
    await next();
  }

  // 获取用户信息（分页）
  async find(ctx) {
    console.log(ctx.query);
    // 默认大小和页码
    const { page_size = 10 } = ctx.query;
    const { page = 1 } = ctx.query
    // 都要除去1 以下的数据
    const currentPage = Math.max(page * 1, 1);
    const pageSize = Math.max(page_size * 1, 1);
    ctx.body = await User
      .find({ name: new RegExp(ctx.query.q, 'gi') })
      .limit(page_size)
      .skip((currentPage - 1) * pageSize);
  }

  // http://localhost:3002/users/61e8d01ace4fa0f9423943fb?fields=educations;employments
  async findById(ctx) {
    const { fields = '' } = ctx.query;
    // console.log(fields.split(';').filter(f => f)); //不要空字符串的
    const selectFields = fields.split(';').filter(f => f).map(f => ' +' + f).join('');
    const populateStr = fields.split(';').filter(f => f).map(f => {
      if (f === 'employments') {
        return 'employments.company employments.job';
      }
      if (f === 'educations') {
        return 'educations.school educations.major';
      }
      return f;
    }).join(' ');
    console.log(populateStr);
    // console.log(selectFields);
    const user = await User.findById(ctx.params.id).select(selectFields).populate(populateStr)
    if (!user) { ctx.throw(404, '用户不存在') }
    ctx.body = user
  }

  async create(ctx) {
    ctx.verifyParams({
      name: { type: 'string', required: true },
      password: { type: 'string', required: true },
    })
    const { name } = ctx.request.body;

    const repeatedUser = await User.findOne({ name });

    if (repeatedUser) { ctx.throw(409, '用户已经占用'); }

    const user = await new User(ctx.request.body).save()

    ctx.body = user
  }

  async update(ctx) {
    ctx.verifyParams({
      name: { type: 'string', required: false },
      password: { type: 'string', required: false },
      avatar_url: { type: 'string', required: false },
      gender: { type: 'string', required: false },
      headline: { type: 'string', required: false },
      locations: { type: 'array', itemType: 'string', required: false },
      business: { type: 'string', required: false },
      employments: { type: 'array', itemType: 'object', required: false },
      educations: { type: 'array', itemType: 'object', required: false },
    })
    // 可以传入你要修改的部分 ，不必全部修改
    const user = await User.findByIdAndUpdate(ctx.params.id, ctx.request.body)
    if (!user) { ctx.throw(404, '用户不存在') }
    ctx.body = user;
  }

  async delete(ctx) {
    const user = await User.findByIdAndRemove(ctx.params.id)
    if (!user) { ctx.throw(404, '用户不存在') }
    ctx.status = 204;
  }

  async login(ctx) {

    ctx.verifyParams({
      name: { type: 'string', required: true },
      password: { type: 'string', required: true },
    });

    const user = await User.findOne(ctx.request.body);

    if (!user) { ctx.throw(401, '用户名或密码不正确'); }

    const { _id, name } = user;
    const token = jsonwebtoken.sign({ _id, name }, secret, { expiresIn: '1d' });
    ctx.body = { token };

  }

  // 列出用户的关注者列表(你关注了谁)
  async listFollowing(ctx) {
    // following 是用户的ObjectId
    const user = await User.findById(ctx.params.id).select('+following').populate('following');
    if (!user) { ctx.throw(404, "未找到用户") }
    ctx.body = user.following;
  }

  // 关注某个用户
  async follow(ctx) {
    if (ctx.params.id.trim() === ctx.state.user._id) ctx.throw(412, '不能关注自己')

    const me = await User.findById(ctx.state.user._id).select("+following");
    // 判断是否已经关注
    const isHave = me.following.map(id => id.toString()).includes(ctx.params.id)
    if (!isHave) {
      me.following.push(ctx.params.id)
      me.save()
    }
    ctx.status = 204;
  }

  // 取注某个用户
  async unfollow(ctx) {
    if (ctx.params.id.trim() === ctx.state.user._id) ctx.throw(412, '不能取关自己')

    const me = await User.findById(ctx.state.user._id).select("+following");
    // 判断是否已经关注
    const isIndex = me.following.map(id => id.toString()).indexOf(ctx.params.id)

    if (isIndex > -1) {
      me.following.splice(isIndex, 1)
      me.save()
    }
    ctx.status = 204;
  }

  // 获取某个用户的粉丝列表(谁关注了你)
  async listFollowers(ctx) {
    const users = await User.find({ following: { $in: [ctx.params.id.trim()] } })
    //  const users = await User.find({ following: ctx.params.id }); // 老师的
    ctx.body = users;
  }

  // 关注话题
  async followTopic(ctx) {
    const me = await User.findById(ctx.state.user._id).select("+followingTopics");
    // 判断是否已经关注
    const isHave = me.followingTopics.map(id => id.toString()).includes(ctx.params.id)
    if (!isHave) {
      me.followingTopics.push(ctx.params.id)
      me.save()
    }
    ctx.status = 204;
  }

  // 取注话题
  async unfollowTopic(ctx) {
    const me = await User.findById(ctx.state.user._id).select("+followingTopics");
    // 判断是否已经关注
    const isIndex = me.followingTopics.map(id => id.toString()).indexOf(ctx.params.id)

    if (isIndex > -1) {
      me.followingTopics.splice(isIndex, 1)
      me.save()
    }
    ctx.status = 204;
  }


  // 获取某个用户的关注话题列表
  async listFollowingTopics(ctx) {
    // followingTopics 是topics的ObjectId (且不要里面的_id)
    const user = await User.findById(ctx.params.id).select('+followingTopics').populate('followingTopics', '-_id');
    if (!user) { ctx.throw(404, "未找到用户") }
    ctx.body = user.followingTopics;
  }

  // 某个用户的所有提问的问题列表
  async listQuestions(ctx) {
    const questions = await Question.find({ questioner: ctx.params.id });
    ctx.body = questions;
  }

  // 指定用户所赞过的答案列表
  async listLikingAnswers(ctx) {
    const user = await User.findById(ctx.params.id).select("+likingAnswers").populate('likingAnswers')
    console.log(user
    );
    if (!user) { ctx.throw(404, '用户不存在') }
    ctx.body = user.likingAnswers
  }

  // 指定用户所踩过的答案列表
  async listDislikingAnswers(ctx) {
    const user = await User.findById(ctx.params.id).select('+dislikingAnswers').populate('dislikingAnswers');
    if (!user) { ctx.throw(404, '用户不存在'); }
    ctx.body = user.dislikingAnswers;
  }

  // 指定用户赞答案(中间件)
  async likeAnswer(ctx, next) {
    const me = await User.findById(ctx.state.user._id).select('+likingAnswers');
    if (!me.likingAnswers.map(id => id.toString()).includes(ctx.params.id)) {
      me.likingAnswers.push(ctx.params.id);
      me.save();
      await Answer.findByIdAndUpdate(ctx.params.id, { $inc: { voteCount: 1 } });
    }
    ctx.status = 204;
    await next();
  }

  // 指定用户踩答案
  async unlikeAnswer(ctx) {
    const me = await User.findById(ctx.state.user._id).select('+likingAnswers')
    const index = me.likingAnswers.map(id => id.toString()).indexOf(ctx.params.id)
    if (index > -1) {
      me.likingAnswers.splice(index, 1)
      me.save()
      // 并让点赞数量减一
      await Answer.findByIdAndUpdate(ctx.params.id, {
        $inc: {
          voteCount: -1
        }
      })
    }
    ctx.status = 204
  }

  // 踩某个答案的时候(中间件)
  async dislikeAnswer(ctx, next) {
    const me = await User.findById(ctx.state.user._id).select('+dislikingAnswers');
    if (!me.dislikingAnswers.map(id => id.toString()).includes(ctx.params.id)) {
      me.dislikingAnswers.push(ctx.params.id);
      me.save();
    }
    ctx.status = 204;
    await next();
  }

  // 取消赞这个答案
  async undislikeAnswer(ctx) {
    const me = await User.findById(ctx.state.user._id).select('+dislikingAnswers');
    const index = me.dislikingAnswers.map(id => id.toString()).indexOf(ctx.params.id);
    if (index > -1) {
      me.dislikingAnswers.splice(index, 1);
      me.save();
    }
    ctx.status = 204;
  }

  // 列出用户的收藏的答案列表
  async listCollectingAnswers(ctx) {
    const user = await User.findById(ctx.params.id).select('+collectingAnswers').populate('collectingAnswers');
    if (!user) { ctx.throw(404, '用户不存在') }
    ctx.body = user.collectingAnswers
  }

  // 用户收藏答案
  async collectAnswer(ctx, next) {
    const me = await User.findById(ctx.state.user._id).select('+collectingAnswers')
    if (!me.collectingAnswers.map(id => id.toString()).includes(ctx.params.id)) {
      me.collectingAnswers.push(ctx.params.id);
      me.save();
    }
    ctx.status = 204;
    await next();
  }
  // 用户取消收藏答案
  async uncollectAnswer(ctx) {
    const me = await User.findById(ctx.state.user._id).select('+collectingAnswers')
    const index = me.collectingAnswers.map(id => id.toString()).indexOf(ctx.params.id)
    if (index > -1) {
      me.collectingAnswers.splice(index, 1)
      me.save()
    }
    ctx.status = 204
  }
}

module.exports = new UsersCtl()